import React from "react";

enum ModalMode {
    CREATE = "CREATE",
    UPDATE = "UPDATE"
}

enum EHookActions {
    CREATE_ITEM = "CREATE_ITEM",
    UPDATE_ITEM = "UPDATE_ITEM",
    CLOSE_MODAL = "CLOSE_MODAL"
}

/**
 * @typedef { Object } - Модель состояния, предоставляемого хуком.
 * @property { <TItem> } item - Начальные данные сущности.
 * @property { EModalMode } modalMode - Режим работы модального окна (например, создания или обновление).
 * @property { boolean } isModalShown - Признак отображения модального окна.
 */
interface IState<T = unknown> {
    item: T;
    modalMode: ModalMode | null;
    isModalShown: boolean;
}

const initialState: IState = {
    item: null,
    modalMode: null,
    isModalShown: false
};

type CreateItemAction<T> = { type: EHookActions.CREATE_ITEM; payload: T };
type UpdateItemAction<T> = { type: EHookActions.UPDATE_ITEM; payload: T };
type CloseModalAction = { type: EHookActions.CLOSE_MODAL };

/**
 * @typedef { Object } - Модель действия, предоставляемого хуком.
 * @property { EModalMode } type - Тип действия.
 * @property { any } payload - Полезная нагрузка для действия.
 */
type HookAction<T = unknown> =
    | CreateItemAction<T>
    | UpdateItemAction<T>
    | CloseModalAction;

/**
 * @function reducer - Функция редьюсера, которая обрабатывает действия модального окна, создает или 
 *  обновляет состояние.
 * @param { IState } state - Текущее состояние для модального окна.
 * @param { HookAction } action - Объект действия, который содержит тип и полезную нагрузку
 *  для действия модального окна.
 * @return { IState } - Обновленное состояние после обработки действия модального окна.
 */
const reducer = (state: IState, action: HookAction) => {

    switch (action.type) {
        case EHookActions.CREATE_ITEM:
            return {
                item: action.payload,
                modalMode: ModalMode.CREATE,
                isModalShown: true
            };
        case EHookActions.UPDATE_ITEM:
            return {
                item: action.payload,
                modalMode: ModalMode.UPDATE,
                isModalShown: true
            };
        case EHookActions.CLOSE_MODAL:
            return initialState;
        default:
            return state;
    }
}

type HookReturnType<T> = {
    state: IState<T>;
    handleCreate: (payload: T) => void;
    handleUpdate: (payload: T) => void;
    handleCloseModal: () => void;
}

/**
 * @function useCrupdateModal - Хук для базовой работы с переиспользуемыми модальными окнами
 *  создания и обновления сущностей.
 * @returns { HookReturnType }
 * 
 */
const useCrupdateModal = <T = unknown>(): HookReturnType<T> => {

    const [state, dispatch] = React.useReducer(reducer, initialState as any);

    /**
     * @function handleCreate - Обрабатывает процесс создания сущности.
     * @param { any } payload - Полезная нагрузка для процесса создания.
     * @returns { void } 
     */
    const handleCreate = (payload: T) => {
        dispatch({ type: EHookActions.CREATE_ITEM, payload });
    }

    /**
     * @function handleUpdate - Обрабатывает процесс обновления сущности.
     * @param { any } payload - Полезная нагрузка для процесса создания.
     * @returns { void } 
     */
    const handleUpdate = (payload: T) => {
        dispatch({ type: EHookActions.UPDATE_ITEM, payload });
    }

    /**
     * @function handleCloseModal - Обрабатывает процесс закрытия модального окна.
     * @returns { void } 
     */
    const handleCloseModal = () => {
        dispatch({ type: EHookActions.CLOSE_MODAL });
    }

    return { state: state as any, handleCreate, handleUpdate, handleCloseModal };
};

export default useCrupdateModal;
